﻿using System;
using System.Data;
using System.Windows.Forms;

namespace Autoupdate.Common
{
    public partial class ConnectServerForm : Form
    {
        private class DBColumn
        {
            public const string ServerName = "ServerName";
            public const string VerifyType = "VerifyType";
            public const string UserName = "UserName";
            public const string Password = "Password";
            public const string DBName = "DBName";
            public const string IsLatest = "IsLatest";
        }

        private string mDBFileName;
        private DataTable mDBSetting;
        private int mLatestIndex;
        private DES mDES;

        public ConnectServerForm(string dbFileName)
        {
            InitializeComponent();

            mDBFileName = dbFileName;
            mDBSetting = new DataTable();
            mDBSetting.Columns.Add(DBColumn.ServerName);
            mDBSetting.Columns.Add(DBColumn.VerifyType);
            mDBSetting.Columns.Add(DBColumn.UserName);
            mDBSetting.Columns.Add(DBColumn.Password);
            mDBSetting.Columns.Add(DBColumn.DBName);
            mDBSetting.Columns.Add(DBColumn.IsLatest);
            mLatestIndex = -1;
            mDES = new DES();

            cboVerifyType.Items.Add("Windows 身份验证");
            cboVerifyType.Items.Add("SQL Server 身份验证");
            cboVerifyType.SelectedIndex = 0;
        }

        public bool TryConnect()
        {
            LoadFile();
            if (mLatestIndex == -1)
                return false;
            DataRow dr = mDBSetting.Rows[mLatestIndex];
            string password = dr[DBColumn.Password].ToString();
            if (!string.IsNullOrEmpty(password))
                password = mDES.DecryptString(password);
            bool success = false;
            string resultText = string.Empty;
            MarqueeProgressForm form = new MarqueeProgressForm();
            form.Text = "正在连接服务器，请稍候...";
            form.DoBackgroundWork += delegate (object sender, EventArgs e)
            {
                success = ConnectToServer(false, dr[DBColumn.ServerName].ToString().Trim(),
                    dr[DBColumn.VerifyType].ToString() == "0",
                    dr[DBColumn.UserName].ToString(),
                    password,
                    dr[DBColumn.DBName].ToString(),
                    out resultText);
            };
            form.ShowDialog();
            if (!string.IsNullOrEmpty(resultText))
            {
                if (success)
                    MessageBox.Show(resultText,
                        "提示",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                else
                    MessageBox.Show(resultText,
                        "错误",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
            }
            return success;
        }

        public bool TryConnectEx()
        {
            LoadFile();
            if (mLatestIndex == -1)
                return false;
            DataRow dr = mDBSetting.Rows[mLatestIndex];
            string password = dr[DBColumn.Password].ToString();
            if (!string.IsNullOrEmpty(password))
                password = mDES.DecryptString(password);
            bool success = false;
            string resultText = string.Empty;
            //MarqueeProgressForm form = new MarqueeProgressForm();
            //form.Text = "正在连接服务器，请稍候...";
            //form.DoBackgroundWork += delegate (object sender, EventArgs e)
            //{
                success = ConnectToServer(false, dr[DBColumn.ServerName].ToString().Trim(),
                    dr[DBColumn.VerifyType].ToString() == "0",
                    dr[DBColumn.UserName].ToString(),
                    password,
                    dr[DBColumn.DBName].ToString(),
                    out resultText);
            //};
            //form.ShowDialog();
            if (!string.IsNullOrEmpty(resultText))
            {
                if (success)
                    MessageBox.Show(resultText,
                        "提示",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                else
                    MessageBox.Show(resultText,
                        "错误",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
            }
            return success;
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            try
            {
                LoadFile();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ex.StackTrace,
                    "错误",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }

        private void cboVerifyType_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (cboVerifyType.SelectedIndex == 0)
                {
                    label3.Enabled = false;
                    txtUserName.Enabled = false;
                    label4.Enabled = false;
                    txtPassword.Enabled = false;
                }
                else
                {
                    label3.Enabled = true;
                    txtUserName.Enabled = true;
                    label4.Enabled = true;
                    txtPassword.Enabled = true;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ex.StackTrace,
                    "错误",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            try
            {
                string serverName = cboServerName.Text.Trim();
                bool useSSPI = cboVerifyType.SelectedIndex == 0;
                string userName = txtUserName.Text;
                string password = txtPassword.Text;
                MarqueeProgressForm form = new MarqueeProgressForm();
                form.Text = "正在连接服务器，请稍候...";
                bool success = false;
                string resultText = string.Empty;
                form.DoBackgroundWork += delegate (object sender2, EventArgs e2)
                {
                    success = ConnectToServer(true, serverName, useSSPI, userName, password, string.Empty, out resultText);
                };
                form.ShowDialog();
                if (!string.IsNullOrEmpty(resultText))
                {
                    if (success)
                        MessageBox.Show(resultText,
                            "提示",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Information);
                    else
                        MessageBox.Show(resultText,
                            "错误",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ex.StackTrace,
                    "错误",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            try
            {
                if (cboDBName.Items.Count == 0)
                {
                    MessageBox.Show("请先连接服务器！",
                        "提示",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                    return;
                }
                if (cboDBName.SelectedIndex == -1)
                {
                    MessageBox.Show("请先选择数据库！",
                        "提示",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Information);
                    return;
                }

                string serverName = cboServerName.Text.Trim();
                bool useSSPI = cboVerifyType.SelectedIndex == 0;
                string userName = txtUserName.Text;
                string password = txtPassword.Text;
                string dbName = cboDBName.Items[cboDBName.SelectedIndex].ToString();

                MarqueeProgressForm form = new MarqueeProgressForm();
                form.Text = "正在连接数据库，请稍候...";
                bool success = false;
                string resultText = string.Empty;
                form.DoBackgroundWork += delegate (object sender2, EventArgs e2)
                {
                    success = ConnectToServer(true, serverName, useSSPI, userName, password, dbName, out resultText);
                };
                form.ShowDialog();
                if (!string.IsNullOrEmpty(resultText))
                {
                    if (success)
                        MessageBox.Show(resultText,
                            "提示",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Information);
                    else
                        MessageBox.Show(resultText,
                            "错误",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Error);
                }
                if (!success)
                    return;

                SaveFile(serverName, useSSPI, userName, password, dbName);
                this.DialogResult = DialogResult.OK;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ex.StackTrace,
                    "错误",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            try
            {
                this.DialogResult = DialogResult.Cancel;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ex.StackTrace,
                    "错误",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }

        private bool ConnectToServer(bool showSuccessfulMessage,
            string serverName, bool useSSPI, string userName, string password, string dbName,
            out string resultText)
        {
            if (string.IsNullOrEmpty(serverName))
            {
                resultText = "服务器名不能为空！";
                return false;
            }

            if (!useSSPI)
            {
                if (string.IsNullOrEmpty(userName))
                {
                    resultText = "用户名不能为空！";
                    return false;
                }
            }

            bool connectToMaster = false;
            if (string.IsNullOrEmpty(dbName))
            {
                dbName = "master";
                connectToMaster = true;
            }

            string connString = string.Empty;
            if (useSSPI)
                connString = "Data Source=" + serverName + ";Initial Catalog=" + dbName + ";"
                    + "Persist Security Info=True;Trusted_Connection=SSPI";
            else
            {
                connString = "Data Source=" + serverName + ";Initial Catalog=" + dbName + ";"
                    + "User Id=" + userName + ";";
                if (!string.IsNullOrEmpty(password))
                    connString += ("Password=" + password + ";");
            }

            DBHelper.ConnectionString = connString;
            bool success = false;
            try
            {
                if (connectToMaster)
                    DBNameItemsClear();//cboDBName.Items.Clear();
                using (DataTable table = new DataTable())
                {
                    DBHelper.FillTableEx("SELECT name FROM master.sys.sysdatabases ORDER BY name", table);
                    if (table.Rows.Count == 0)
                    {
                        resultText = "";
                        return false;
                    }
                    if (connectToMaster)
                    {
                        foreach (DataRow dr in table.Rows)
                            DBNameItemsAdd(dr[0].ToString());// cboDBName.Items.Add(dr[0].ToString());
                    }
                }
                if (connectToMaster)
                {
                    DBNameResetSelectedIndex();// cboDBName.SelectedIndex = -1;
                    if (showSuccessfulMessage)
                        resultText = "连接服务器成功！";
                    else
                        resultText = string.Empty;
                }
                else
                {
                    if (showSuccessfulMessage)
                        resultText = "连接数据库 '" + dbName + "' 成功！";
                    else
                        resultText = string.Empty;
                }
                success = true;
            }
            catch (Exception)
            {
                DBHelper.ConnectionString = string.Empty;
                resultText = "连接服务器失败";
                //MessageBox.Show(ex.Message + ex.StackTrace,
                //     "错误",
                //     MessageBoxButtons.OK,
                //     MessageBoxIcon.Error);
            }
            return success;
        }

        delegate void DBNameItemsClearCallBack();
        private void DBNameItemsClear()
        {
            if (this.cboDBName.InvokeRequired)
                this.Invoke(new DBNameItemsClearCallBack(DBNameItemsClear), new object[] { });
            else
                this.cboDBName.Items.Clear();
        }

        delegate void DBNameItemsAddCallBack(object item);
        private void DBNameItemsAdd(object item)
        {
            if (this.cboDBName.InvokeRequired)
                this.Invoke(new DBNameItemsAddCallBack(DBNameItemsAdd), new object[] { item });
            else
                this.cboDBName.Items.Add(item);
        }

        delegate void DBNameResetSelectedIndexCallBack();
        private void DBNameResetSelectedIndex()
        {
            if (this.cboDBName.InvokeRequired)
                this.Invoke(new DBNameResetSelectedIndexCallBack(DBNameResetSelectedIndex), new object[] { });
            else
                this.cboDBName.SelectedIndex = -1;
        }

        private void LoadFile()
        {
            mLatestIndex = -1;

            if (!Util.XmlToDataTable(mDBFileName, ref mDBSetting))
                return;

            for (int i = 0; i < mDBSetting.Rows.Count; ++i)
            {
                if (mDBSetting.Rows[i][DBColumn.IsLatest].ToString().ToUpper() == "TRUE")
                {
                    mLatestIndex = i;
                    break;
                }
            }
            if (mDBSetting.Rows.Count > 0 && mLatestIndex == -1)
                mLatestIndex = 0;

            cboServerName.Items.Clear();
            foreach (DataRow dr in mDBSetting.Rows)
                cboServerName.Items.Add(dr[DBColumn.ServerName].ToString());
            if (mLatestIndex != -1)
            {
                DataRow dr = mDBSetting.Rows[mLatestIndex];
                cboServerName.SelectedIndex = cboServerName.Items.IndexOf(dr[DBColumn.ServerName].ToString());
                if (dr[DBColumn.VerifyType].ToString() == "0")
                {
                    cboVerifyType.SelectedIndex = 0;
                    txtUserName.Text = string.Empty;
                    txtPassword.Text = string.Empty;
                }
                else
                {
                    cboVerifyType.SelectedIndex = 1;
                    txtUserName.Text = dr[DBColumn.UserName].ToString();
                    string password = dr[DBColumn.Password].ToString();
                    if (!string.IsNullOrEmpty(password))
                        password = mDES.DecryptString(password);
                    txtPassword.Text = password;
                }
            }
        }

        private void SaveFile(string serverName, bool useSSPI, string userName, string password, string dbName)
        {
            int index = -1;
            for (int i = 0; i < mDBSetting.Rows.Count; ++i)
            {
                if (mDBSetting.Rows[i][DBColumn.ServerName].ToString() == serverName)
                {
                    index = i;
                    break;
                }
            }
            foreach (DataRow dr in mDBSetting.Rows)
                dr[DBColumn.IsLatest] = "FALSE";
            if (index == -1)
            {
                DataRow newRow = mDBSetting.NewRow();
                newRow[DBColumn.ServerName] = serverName;
                newRow[DBColumn.VerifyType] = useSSPI ? "0" : "1";
                if (useSSPI)
                {
                    newRow[DBColumn.UserName] = string.Empty;
                    newRow[DBColumn.Password] = string.Empty;
                }
                else
                {
                    newRow[DBColumn.UserName] = userName;
                    if (!string.IsNullOrEmpty(password))
                        newRow[DBColumn.Password] = mDES.EncryptString(password);
                    else
                        newRow[DBColumn.Password] = password;
                }
                newRow[DBColumn.DBName] = dbName;
                newRow[DBColumn.IsLatest] = "TRUE";
                mDBSetting.Rows.Add(newRow);
            }
            else
            {
                DataRow curRow = mDBSetting.Rows[index];
                curRow[DBColumn.ServerName] = serverName;
                curRow[DBColumn.VerifyType] = useSSPI ? "0" : "1";
                if (useSSPI)
                {
                    curRow[DBColumn.UserName] = string.Empty;
                    curRow[DBColumn.Password] = string.Empty;
                }
                else
                {
                    curRow[DBColumn.UserName] = userName;
                    if (!string.IsNullOrEmpty(password))
                        curRow[DBColumn.Password] = mDES.EncryptString(password);
                    else
                        curRow[DBColumn.Password] = password;
                }
                curRow[DBColumn.DBName] = dbName;
                curRow[DBColumn.IsLatest] = "TRUE";
            }
            Util.DataTableToXml(mDBSetting, mDBFileName);
        }
    }
}
